package com.korustar.autumnal.ant;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.log4j.BasicConfigurator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import com.korustar.autumnal.XmlBeanInterpretation;
import com.korustar.autumnal.codemodel.CodeModelBeanConstructionBuilder;
import com.korustar.autumnal.codemodel.CodeModelContainerBuilder;
import com.korustar.autumnal.codemodel.CodeModelContainerModel;
import com.korustar.autumnal.codemodel.CodeModelParameterBuilder;
import com.korustar.autumnal.codemodel.CodeModelSimpleOutputter;
import com.sun.codemodel.JClassAlreadyExistsException;

public class AutumnalAntTask extends Task {
	private String applicationContextFilename;
	private String outputDir;
	private String containerClassName=CodeModelContainerBuilder.DEFAULT_CONTAINER_CLASS_NAME;

	@Override
	public void execute() throws BuildException {
		BasicConfigurator.configure();
		if(this.applicationContextFilename==null) {
			throw new BuildException("You need to set applicationContext");
		}
		File file = new File(this.applicationContextFilename);
		BeanDefinitionRegistry registry = XmlBeanInterpretation.getBeanRegistry(file);

		CodeModelContainerBuilder classBuilder= new CodeModelContainerBuilder();
		CodeModelContainerModel model= new CodeModelContainerModel();
		model.setContainerClassName(this.getContainerClassName());
		CodeModelParameterBuilder parameterBuilder= new CodeModelParameterBuilder();
		classBuilder.setParameterBuilder(parameterBuilder);
		CodeModelBeanConstructionBuilder constructionBuilder= new CodeModelBeanConstructionBuilder();
		classBuilder.setConstructionBuilder(constructionBuilder);
		constructionBuilder.setParameterBuilder(parameterBuilder);
		
		CodeModelSimpleOutputter outputter= new CodeModelSimpleOutputter();
		outputter.setFolderName(this.outputDir);
		

		try {
			classBuilder.build(registry, model);
			try {
				if(this.outputDir!=null) {
					OutputStream os;
					String filename= this.outputDir+"/"+folderize(this.getContainerClassName())+".java";
					File f= new File(filename);
					if(!f.exists()) {
						if(!f.getParentFile().exists()) {
							f.getParentFile().mkdirs();
						}
					}
					System.out.println("Writing to "+filename);
					os= new FileOutputStream(filename);
					model.outputToStream(os);
					System.out.println("Done");
				} else {
					System.out.println(model.getOutput());
				}
			} catch (IOException e) {
				System.out.println(e.getMessage());
				throw new BuildException("Problem outputting class", e);
			}
		} catch (JClassAlreadyExistsException e1) {
			throw new BuildException("Problem building class", e1);
		}
		System.out.println("Done");
	}
	
	private String folderize(String containerClassName2) {
		return containerClassName2.replace(".", "/");
	}

	public void setApplicationContext(String file) {
		this.applicationContextFilename= file;
	}
	
	public void setOutputDir(String directory) {
		this.outputDir= directory;
	}

	public void setContainerClassName(String containerClassName) {
		this.containerClassName = containerClassName;
	}

	public String getContainerClassName() {
		return this.containerClassName;
	}

	
	

}
